/**
 * @file app_midi.h
 * @brief MIDI应用层 - 简化版 (3阶段钢琴键打击状态机)
 * @date 2025-11-04
 */

#ifndef __APP_MIDI_H__
#define __APP_MIDI_H__

#ifdef __cplusplus
extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include <stdint.h>
#include <stdbool.h>

/* Exported types ------------------------------------------------------------*/

/**
 * @brief MIDI琴键状态枚举
 */
typedef enum {
    MIDI_STATE_IDLE = 0,        /* 空闲 */
    MIDI_STATE_STAGE1,          /* 阶段1: 全功率启动 */
    MIDI_STATE_STAGE2_LOW,      /* 阶段2-低: 力度控制 (低电平阶段) */
    MIDI_STATE_STAGE2_HIGH,     /* 阶段2-高: 力度控制 (高电平阶段) */
    MIDI_STATE_STAGE3_1,        /* 阶段3-1: 第一悬停 */
    MIDI_STATE_STAGE3_2         /* 阶段3-2: 第二悬停 (连续) */
} midi_state_e;

/* Exported constants --------------------------------------------------------*/

#define MIDI_CH_COUNT               8       /* 每块板8个通道 */
#define MIDI_TIMEOUT_MS             7000    /* 7秒自动关闭超时 */

/* 时间1: 全功率启动 (默认值, 可通过B0 0E 01调整) */
#define MIDI_TIME1_DEFAULT_MS       40      /* 默认40ms */
#define MIDI_TIME1_MIN_MS           10      /* 最小10ms */
#define MIDI_TIME1_MAX_MS           40      /* 最大40ms */

/* 时间2: 力度控制 (根据velocity计算, 可通过B0 0E 02调整基准) */
#define MIDI_TIME2_BASE_MS          63      /* 基准63ms (velocity=0x7F时) */

/* 时间3-1: 第一悬停持续时间 (固定100ms) */
#define MIDI_TIME3_1_DURATION_MS    100

/* Exported functions prototypes ---------------------------------------------*/

/**
 * @brief 初始化MIDI应用层
 * @return 0成功, -1失败
 */
int app_midi_init(void);

/**
 * @brief MIDI周期性任务 (处理3阶段状态机)
 * @note 应每1ms调用一次以确保精确时序
 */
void app_midi_task(void);

/**
 * @brief 音符按下 (启动3阶段打击序列) - 16位精度版本
 * @param note MIDI音符号 (0x15-0x6C)
 * @param velocity_16 MIDI力度 (0x0000-0xFFFF, 16位精度)
 * @return 0成功, -1失败
 */
int app_midi_note_on_16(uint8_t note, uint16_t velocity_16);

/**
 * @brief 音符按下 (启动3阶段打击序列) - 7位精度版本 (兼容接口)
 * @param note MIDI音符号 (0x15-0x6C)
 * @param velocity MIDI力度 (0x00-0x7F)
 * @return 0成功, -1失败
 */
int app_midi_note_on(uint8_t note, uint8_t velocity);

/**
 * @brief 音符关闭 (停止PWM输出)
 * @param note MIDI音符号 (0x15-0x6C)
 * @return 0成功, -1失败
 */
int app_midi_note_off(uint8_t note);

/**
 * @brief 全部音符关闭 (紧急停止所有通道)
 * @return 0成功, -1失败
 */
int app_midi_all_notes_off(void);

/**
 * @brief 设置板号
 * @param board_id 板号 (1-11)
 */
void app_midi_set_board_id(uint8_t board_id);

/**
 * @brief 处理控制变化命令 (设置模式)
 * @param cc_num 控制变化号 (0x0E=设置模式)
 * @param cc_val 控制变化值 (0x01-0x04, 0x7F)
 * @return 0成功, -1失败
 * @note 支持B0 0E xx命令调整时间1/2/3-1/3-2参数
 */
int app_midi_process_cc(uint8_t cc_num, uint8_t cc_val);

/**
 * @brief 设定模式下处理 NOTE ON（用 velocity 调整参数）
 * @param velocity 7位力度值 (1-127)
 * @return 0成功, -1失败
 */
int app_midi_setup_adjust(uint8_t velocity);

#ifdef __cplusplus
}
#endif

#endif /* __APP_MIDI_H__ */

/******************************** 文件结束 *********************************/
